/**
 * @file TruthTable.hh
 * @author Xiaoze Lin (linxiaoze96@gmail.com)
 * @brief The truth table for gate evaluation.
 * @version 0.1
 *
 * @copyright Copyright (c) 2024
 *
 */
#pragma once

#include "Common.hh"
#include "define/Define.hh"

namespace ifsim {

/* 1 input gates: */
static const GateValue TruthTable1[T_LAST_GTYPE][NUM_VALS] = {
    /*  VAL_ZERO    VAL_ONE		VAL_X		VAL_D		VAL_DBAR	VAL_Z	*/
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_JUNK */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_INPUT */
    {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z}, /* T_OUTPUT */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_XOR */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_XNOR */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_DELAY_ELEMENT */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_AND */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_NAND */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_OR */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_NOR */
    {VAL_ONE, VAL_ZERO, VAL_X, VAL_DBAR, VAL_D, VAL_Z}, /* T_NOT */
    {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z}, /* T_BUF */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TIE1 */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TIE0 */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TIEX */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TIEZ */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_MUX_2 */
    {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z}, /* T_BUF_FB */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_BUS */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_BUS_GOHIGH */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_BUS_GOLOW */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_BUS_X */
    {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_X}, /* T_BUFZ */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TRISTATEBUF */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_TRISTATEINV */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_DLA_PRI */
    {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* T_DFF_PRI */
};

/* 2 input gates */
static const GateValue TruthTable2[T_LAST_GTYPE][NUM_VALS][NUM_VALS] = {
    /*   0		1		VAL_X		VAL_D		VAL_DBAR   VAL_Z	*/
    /* T_JUNK */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_INPUT */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_OUTPUT */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_XOR */
    {{VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z}, /* 0 */
     {VAL_ONE, VAL_ZERO, VAL_X, VAL_DBAR, VAL_D, VAL_Z}, /* 1 */
     {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* VAL_X */
     {VAL_D, VAL_DBAR, VAL_X, VAL_ZERO, VAL_ONE, VAL_Z}, /* VAL_D */
     {VAL_DBAR, VAL_D, VAL_X, VAL_ONE, VAL_ZERO, VAL_Z}, /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},        /* VAL_Z */
    /* T_XNOR */
    {{VAL_ONE, VAL_ZERO, VAL_X, VAL_DBAR, VAL_D, VAL_Z}, /* 0 */
     {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z}, /* 1 */
     {VAL_X, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* VAL_X */
     {VAL_DBAR, VAL_D, VAL_X, VAL_ONE, VAL_ZERO, VAL_Z}, /* VAL_D */
     {VAL_D, VAL_DBAR, VAL_X, VAL_ZERO, VAL_ONE, VAL_Z}, /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},        /* VAL_Z */
    /* T_DELAY_ELEMENT */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_AND */
    {{VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_Z}, /* 0 */
     {VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z},        /* 1 */
     {VAL_ZERO, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},             /* VAL_X */
     {VAL_ZERO, VAL_D, VAL_X, VAL_D, VAL_ZERO, VAL_Z},          /* VAL_D */
     {VAL_ZERO, VAL_DBAR, VAL_X, VAL_ZERO, VAL_DBAR, VAL_Z},    /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},               /* VAL_Z */
    /* T_NAND */
    {{VAL_ONE, VAL_ONE, VAL_ONE, VAL_ONE, VAL_ONE, VAL_Z}, /* 0 */
     {VAL_ONE, VAL_ZERO, VAL_X, VAL_DBAR, VAL_D, VAL_Z},   /* 1 */
     {VAL_ONE, VAL_X, VAL_X, VAL_X, VAL_X, VAL_Z},         /* VAL_X */
     {VAL_ONE, VAL_DBAR, VAL_X, VAL_DBAR, VAL_ONE, VAL_Z}, /* VAL_D */
     {VAL_ONE, VAL_D, VAL_X, VAL_ONE, VAL_D, VAL_Z},       /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},          /* VAL_Z */
    /* T_OR */
    {{VAL_ZERO, VAL_ONE, VAL_X, VAL_D, VAL_DBAR, VAL_Z},   /* 0 */
     {VAL_ONE, VAL_ONE, VAL_ONE, VAL_ONE, VAL_ONE, VAL_Z}, /* 1 */
     {VAL_X, VAL_ONE, VAL_X, VAL_X, VAL_X, VAL_Z},         /* VAL_X */
     {VAL_D, VAL_ONE, VAL_X, VAL_D, VAL_ONE, VAL_Z},       /* VAL_D */
     {VAL_DBAR, VAL_ONE, VAL_X, VAL_ONE, VAL_DBAR, VAL_Z}, /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},          /* VAL_Z */
    /* T_NOR */
    {{VAL_ONE, VAL_ZERO, VAL_X, VAL_DBAR, VAL_D, VAL_Z},        /* 0 */
     {VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_ZERO, VAL_Z}, /* 1 */
     {VAL_X, VAL_ZERO, VAL_X, VAL_X, VAL_X, VAL_Z},             /* VAL_X */
     {VAL_DBAR, VAL_ZERO, VAL_X, VAL_DBAR, VAL_ZERO, VAL_Z},    /* VAL_D */
     {VAL_D, VAL_ZERO, VAL_X, VAL_ZERO, VAL_D, VAL_Z},          /* VAL_DBAR */
     {VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z, VAL_Z}},               /* VAL_Z */
    /* T_NOT */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUF */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TIE1 */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TIE0 */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TIEX */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TIEZ */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_MUX_2 */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUF_FB */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUS */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUS_GOHIGH */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUS_GOLOW */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUS_X */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_BUFZ */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TRISTATEBUF */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_TRISTATEINV */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_DLA_PRI */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
    /* T_DFF_PRI */
    {{
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     },
     {
         VAL_X,
     }},
};
}  // namespace ifsim